/*
-----------------------------------------------------------------------------
This source file is part of SapphireEngine

SapphireEngine is a Framework for Turn Based Strategy games.
For more information see http://code.google.com/p/sapphire-engine/

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.

-----------------------------------------------------------------------------
*/
#ifndef _MAIN_MENU_SCREEN_H
#define _MAIN_MENU_SCREEN_H

#include "SapphirePrerequisites.h"

#include <OIS/OIS.h>
#include <OgreCEGUIRenderer.h>
#include <list>
#include "PartTool.h"
#include "SapphireMemoryManager.h"

#define CAMERASTEP 10.0

namespace SapphireEngine
{
	namespace GUI
	{
		class StatsScreen : public Screen
		{
		public:
			StatsScreen(){}			
		};
		class TechScreen : public Screen
		{
		public:
			TechScreen(){}
		};
		class UnitsScreen : public Screen
		{
		public:
			UnitsScreen()
			{
				mSceneMgr = Ogre::Root::getSingletonPtr()->createSceneManager(Ogre::ST_GENERIC,"Unit Create SceneManager");

				mCamera = mSceneMgr->createCamera("Camera");

				mSceneMgr->setAmbientLight(Ogre::ColourValue(0.2, 0.2, 0.2));
				Ogre::Light *light = mSceneMgr->createLight("Light");

				Ogre::RenderTexture *tex= Ogre::Root::getSingletonPtr()->getTextureManager()->createManual
										  ("Unit", "Default", Ogre::TEX_TYPE_2D, 512, 512, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET)
										   ->getBuffer()->getRenderTarget();

				Ogre::Viewport *v = tex->addViewport(mCamera);
				v->setOverlaysEnabled(false);
				v->setClearEveryFrame(true);
				v->setBackgroundColour(Ogre::ColourValue::Black);

				CEGUI::Texture *cTex = static_cast<CEGUI::OgreCEGUIRenderer*>(getSystem()->getRenderer())->createTexture((CEGUI::utf8*)"Unit");

				CEGUI::Imageset *imageSet = CEGUI::ImagesetManager::getSingleton().createImageset((CEGUI::utf8*)"UnitImageset", cTex);
				imageSet->defineImage((CEGUI::utf8*)"UnitImage", 
				   CEGUI::Point(0.0f, 0.0f),
				   CEGUI::Size(cTex->getWidth(), cTex->getHeight()),
				   CEGUI::Point(0.0f,0.0f));

				CEGUI::Window *wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 1/PlayerTab/Tab 3/UnitImg");
				wnd->setProperty("Image", CEGUI::PropertyHelper::imageToString(&imageSet->getImage((CEGUI::utf8*)"UnitImage")));
			}
			void subscribeEvents()
			{
				CEGUI::Event::Connection connect;
				
			}	
			// MouseListener
			bool mouseMoved(const OIS::MouseEvent &arg)
			{
				return true;
			}
			bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
			{
				return true;
			}
			bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
			{
				return true;
			}
			// KeyListener
			bool keyPressed(const OIS::KeyEvent &arg)
			{
				return true;
			}
			bool keyReleased(const OIS::KeyEvent &arg)
			{
				return true;
			}
		private:
			Ogre::SceneManager *mSceneMgr;
			Ogre::Camera *mCamera;
		};
		class FormationsScreen : public Screen
		{
		public:
			FormationsScreen(){}
		};

		class DisplayScreen : public Screen
		{
		public:
			DisplayScreen(){}
		};

		class SoundScreen : public Screen
		{
		public:
			SoundScreen(){}
		};

		class KeyScreen : public Screen
		{
		public:
			KeyScreen(){}
		};

		class MainMenuScreen : public Screen
		{
		public:
			MainMenuScreen(CEGUI::String layoutFile):Screen(layoutFile)
			{
				//Player menu
				Screen* scrn = new StatsScreen();
				getMemoryManager()->addPointer(scrn,"Stats Screen");
				mScreens.insert(ScreenMapItem("Stats",scrn));
				scrn = new TechScreen();
				getMemoryManager()->addPointer(scrn,"Tech Screen");
				mScreens.insert(ScreenMapItem("Tech Tree",scrn));
				scrn = new UnitsScreen();
				getMemoryManager()->addPointer(scrn,"Unit Screen");
				mScreens.insert(ScreenMapItem("Create/Modify Unit",scrn));
				scrn = new FormationsScreen();
				getMemoryManager()->addPointer(scrn,"Formation Screen");
				mScreens.insert(ScreenMapItem("Formations",scrn));
				//Settings menu
				scrn = new DisplayScreen();
				getMemoryManager()->addPointer(scrn,"Display Screen");
				mScreens.insert(ScreenMapItem("Display",scrn));
				scrn = new SoundScreen();
				getMemoryManager()->addPointer(scrn,"Sound Screen");
				mScreens.insert(ScreenMapItem("Sound",scrn));
				scrn = new KeyScreen();
				getMemoryManager()->addPointer(scrn,"Keys Screen");
				mScreens.insert(ScreenMapItem("Key Bindings",scrn));

				//Admin menu
				scrn = new StatsScreen();
				getMemoryManager()->addPointer(scrn,"Stats Screen");
				mScreens.insert(ScreenMapItem("Temp",scrn));
				scrn = new PartTool();
				getMemoryManager()->addPointer(scrn,"Part Screen");
				mScreens.insert(ScreenMapItem("Manage Parts",scrn));

				mCurrentScreen = mScreens.find("Stats");
				mCurrentScreen->second->subscribeEvents();
			}
			~MainMenuScreen()
			{
				for (ScreenMapIterator itr=mScreens.begin();itr!=mScreens.end();itr++)
				{
					getMemoryManager()->removePointer(itr->second);
					delete itr->second;
				}
				mScreens.clear();
				unSubscribeEvents();
			}
				
			// Events
			void subscribeEvents()
			{
				CEGUI::Event::Connection connect;
				
				//Handle Exit Options
				//-------------------------------------------------------------------------------------------------------------------------------
					//Show/Hide exit panel
				Window *wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame");
				connect = wnd->subscribeEvent(FrameWindow::EventCloseClicked,CEGUI::Event::Subscriber(&MainMenuScreen::_exitPanel, this));
				mEventConnections.push_front(connect);
						
					//Logout button clicked
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/ExitOpts/LogoutBtn");
				connect = wnd->subscribeEvent(Window::EventMouseClick,CEGUI::Event::Subscriber(&MainMenuScreen::_logout, this));
				mEventConnections.push_front(connect);
					//Exit button clicked
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/ExitOpts/ExitBtn");
				connect = wnd->subscribeEvent(Window::EventMouseClick,CEGUI::Event::Subscriber(&MainMenuScreen::_exit, this));
				mEventConnections.push_front(connect);
				//--------------------------------------------------------------------------------------------------------------------------------
				//Handle Tab Controls
				//--------------------------------------------------------------------------------------------------------------------------------
					//On main Tab change
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab");
				connect = wnd->subscribeEvent(TabControl::EventSelectionChanged,CEGUI::Event::Subscriber(&MainMenuScreen::_changeMainTab, this));
				mEventConnections.push_front(connect);
					//On Player Tab change
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 1/PlayerTab");
				connect = wnd->subscribeEvent(TabControl::EventSelectionChanged,CEGUI::Event::Subscriber(&MainMenuScreen::_changePlayerTab, this));
				mEventConnections.push_front(connect);
					//On Settings Tab change
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 2/SettingsTab");
				connect = wnd->subscribeEvent(TabControl::EventSelectionChanged,CEGUI::Event::Subscriber(&MainMenuScreen::_changeSettingsTab, this));
				mEventConnections.push_front(connect);
					//On Admin Tab change
				wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab");
				connect = wnd->subscribeEvent(TabControl::EventSelectionChanged,CEGUI::Event::Subscriber(&MainMenuScreen::_changeAdminTab, this));
				mEventConnections.push_front(connect);
				
			}
			
			// MouseListener
			bool mouseMoved(const OIS::MouseEvent &arg)
			{
				mCurrentScreen->second->mouseMoved(arg);
				return true;
			}
			bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
			{
				mCurrentScreen->second->mousePressed(arg,id);
				return true;
			}
			bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
			{
				mCurrentScreen->second->mouseReleased(arg,id);
				return true;
			}
			// KeyListener
			bool keyPressed(const OIS::KeyEvent &arg)
			{
				mCurrentScreen->second->keyPressed(arg);
				if (arg.key == OIS::KC_ESCAPE)
					mContinue=false;
				return true;
			}
			bool keyReleased(const OIS::KeyEvent &arg)
			{
				mCurrentScreen->second->keyReleased(arg);
				return true;
			}
			bool update(const FrameEvent &evt)
			{
				return mCurrentScreen->second->update(evt);
			}
			
		private:
			bool _changeMainTab(const CEGUI::EventArgs & arg)
			{
				TabControl *wnd = static_cast<TabControl*>(getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab"));
				TabControl *curTab = static_cast<TabControl*>(wnd->getTabContentsAtIndex(wnd->getSelectedTabIndex())->getChildAtIdx(0));
				Ogre::String str(curTab->getTabContentsAtIndex(curTab->getSelectedTabIndex())->getText().c_str());

				mCurrentScreen->second->unSubscribeEvents();
				mCurrentScreen = mScreens.find(str);
				mCurrentScreen->second->subscribeEvents();
				return true;
			}
			bool _changePlayerTab(const CEGUI::EventArgs & arg)
			{
				TabControl *wnd = static_cast<TabControl*>(getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 1/PlayerTab"));
				Ogre::String str(wnd->getTabContentsAtIndex(wnd->getSelectedTabIndex())->getText().c_str());

				mCurrentScreen->second->unSubscribeEvents();
				mCurrentScreen = mScreens.find(str);
				mCurrentScreen->second->subscribeEvents();
				return true;
			}
			bool _changeSettingsTab(const CEGUI::EventArgs & arg)
			{
				TabControl *wnd = static_cast<TabControl *>(getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 2/SettingsTab"));
				Ogre::String str(wnd->getTabContentsAtIndex(wnd->getSelectedTabIndex())->getText().c_str());

				mCurrentScreen->second->unSubscribeEvents();
				mCurrentScreen = mScreens.find(str);
				mCurrentScreen->second->subscribeEvents();
				return true;
			}
			bool _changeAdminTab(const CEGUI::EventArgs & arg)
			{
				TabControl *wnd = static_cast<TabControl *>(getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/MainTab/Tab 3/AdminTab"));
				Ogre::String str(wnd->getTabContentsAtIndex(wnd->getSelectedTabIndex())->getText().c_str());

				mCurrentScreen->second->unSubscribeEvents();
				mCurrentScreen = mScreens.find(str);
				mCurrentScreen->second->subscribeEvents();
				return true;
			}
			bool _exitPanel(const CEGUI::EventArgs & arg)
			{
				Window *wnd = getWindowManager()->getWindow((CEGUI::utf8*)"Sapphire/Frame/ExitOpts");
				if(wnd->isVisible())
					wnd->hide();
				else
					wnd->show();
				return true;
			}
			bool _logout(const CEGUI::EventArgs & arg)
			{
				return true;
			}
			bool _exit(const CEGUI::EventArgs & arg)
			{
				mContinue=false;
				return true;
			}
			
			ScreenMapConstIterator mCurrentScreen;
			ScreenMap mScreens;
		};
	}
}
#endif